const io = require('socket.io-client');

const signalTypes = require('../../signal_types');
const signal = require('./signalBus');
const signalServerStatus = require("../../signal_server_status");


console.log('process.env.SIGNAL_SEVER_URL:',process.env.SIGNAL_SEVER_URL);
const initSignalClient = () => {
  // todo 因为我们是在electron的main进程中启动的, 这里没有localStorage, 想要debug需要自己打log
  // isDev && (localStorage.debug = '*');

  // 注意: 我们这里肯定是跨域(我们客户端是用electron起的), So在服务器端上socket.io初始化时,要加上一句cors:true
  const SignalClient = io(
    process.env.SIGNAL_SEVER_URL,
    {
      reconnection: false,
      timeout: process.env.SIGNAL_SERVER_CONNECT_TIMEOUT_TIME, //socket.io给的默认值是 20000
      autoConnect: false  //默认为true
      /*
         设置为false后, 就需要以下这样连接
         socket.connect();
         // or
         socket.io.open(err=>{});
     */
    }
  );

  // 第一次如果使用 socket.io.open(err=>{}) 是不会触发 connection事件的(不论本地的还是服务端的)
  SignalClient.connect();
  let first = true;
  // Fired when an namespace middleware error occurs.
  SignalClient.on('connect_error',()=>{
    console.log('--- --- --- connect_error --- --- ---')
    if(!first) return;
    first = false;
    tryReconnect()
  });


  const tryReconnect = () => {
    console.log(`${process.env.SIGNAL_SERVER_RECONNECTION_TIME}ms后重连`);
    setTimeout(() => {
      console.log('正在重连 --- --- ---');
      signal.emit(signalTypes["SIGNAL_SERVER:STATE_CHANGED"], signalServerStatus.CONNECTING);
      SignalClient.io.open((err) => {
        if (err) {
          console.log('socket.io.open err --- --- ---');
          signal.emit(signalTypes["SIGNAL_SERVER:STATE_CHANGED"], signalServerStatus.CONNECT_FAILED);
          tryReconnect();
        }
      });

    }, process.env.SIGNAL_SERVER_RECONNECTION_TIME);
  }

  //服务器挂掉的时候 只会触发disconnect, 而不会触发 connect_error (或socket.io.on('error'))
  SignalClient.on("disconnect", () => {
    console.log('disconnect--- --- ---');
    signal.emit(signalTypes["SIGNAL_SERVER:STATE_CHANGED"], signalServerStatus.CONNECT_FAILED);
    tryReconnect()
  });


  SignalClient.on('connect', () => {
    if(first) first = false;
    console.log('connection successful --- --- --');
    signal.emit(signalTypes['SIGNAL_SERVER:STATE_CHANGED'], signalServerStatus.CONNECTED);
  });

  // handle the event sent with socket.send()
  SignalClient.on('message', (_data) => {
    const {event, data} = _data;
    signal.emit(event, data);
  });

  signal.send = (event, data) => {
    //socket.io会自动序列化以及反序列化
    SignalClient.send({
      event,
      data
    });
  };
};

module.exports = initSignalClient;
